/**
 * Copyright &copy; 2012-2014 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 */
package com.msk.sys.service;


import com.msk.common.exception.GlobalException;
import com.msk.common.utils.Digests;
import com.msk.common.utils.Encodes;
import com.msk.common.utils.IdGen;
import com.msk.common.utils.StringUtils;
import com.msk.common.utils.ip.IpUtils;
import com.msk.sys.domain.Menu;
import com.msk.sys.domain.Office;
import com.msk.sys.domain.Role;
import com.msk.sys.domain.User;
import com.msk.sys.mapper.MenuDao;
import com.msk.sys.mapper.RoleDao;
import com.msk.sys.mapper.UserDao;
import com.msk.wlhy.domain.HtCarFiles;
import com.msk.wlhy.domain.HtDriverFile;
import com.msk.wlhy.mapper.HtCarFilesDao;
import com.msk.wlhy.mapper.HtDriverFileDao;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 系统管理，安全相关实体的管理类,包括用户、角色、菜单.
 * @author ThinkGem
 * @version 2013-12-05
 */
@Lazy(false)
@Service
@Transactional(readOnly = true)
public class SystemService extends BaseService implements InitializingBean {

	public static final String HASH_ALGORITHM = "SHA-1";
	public static final int HASH_INTERATIONS = 1024;
	public static final int SALT_SIZE = 8;

	@Autowired
	private UserDao userDao;
	@Autowired
	private RoleDao roleDao;
	@Autowired
	private MenuDao menuDao;
	@Autowired
	private HtCarFilesDao htCarFilesDao;
	@Autowired
	private HtDriverFileDao htDriverFileDao;
	// -- User Service --//


	/**
	 * 根据用户名获取用户
	 * @param loginName
	 * @return
	 */
	public User getByLoginName(String loginName) {
		User user = new User();
		user.setLoginName(loginName);
		return userDao.getByLoginName(user);
	}

	/**
	 * 根据手机号及身份获取用户
	 * @param loginName
	 * @return
	 */
	public User getByMobile(String mobile, String userIdentity) {
		User userResult = null;
		User user = new User();
		user.setMobile(mobile);
		user.setUserIdentity(userIdentity);
		List<User> userList = userDao.getByPhone(user);
		if (CollectionUtils.isNotEmpty(userList)) {
			userResult = userList.get(0);
		}
		return userResult;
	}

	/**
	 * 根据手机号获取用户
	 * @param user
	 * @return
	 */
	public List<User> getByPhone(User user) {
		return userDao.getByPhone(user);
	}


//	public Page<User> findUser(Page<User> page, User user) {
//		// 设置分页参数
//		user.setPage(page);
//		// 执行分页查询
//		page.setList(userDao.findList(user));
//		return page;
//	}

	/**
	 * 获取用户
	 * @param id
	 * @returna
	 */
	public User getUser(String id) {
		return userDao.get(id);
	}

	/**
	 * 无分页查询人员列表
	 * @param user
	 * @return
	 */
	public List<User> findUser(User user) {
		// 生成数据权限过滤条件（dsf为dataScopeFilter的简写，在xml中使用 ${sqlMap.dsf}调用权限SQL）
		List<User> list = userDao.findList(user);
		return list;
	}



	/**
	 * 无分页查询人员列表
	 * @param user
	 * @return
	 */
	public List<User> findList(User user) {
		// 生成数据权限过滤条件（dsf为dataScopeFilter的简写，在xml中使用 ${sqlMap.dsf}调用权限SQL）
		//user.getSqlMap().put("dsf", dataScopeFilter(user.getCurrentUser(), "o", "a"));
		List<User> list = userDao.findList(user);
		return list;
	}


	/**
	 * 无分页等号查询name 和 loginname
	 * @param user
	 * @return
	 */
	public List<User> findListPreciseName(User user) {
		List<User> list = userDao.findListPreciseName(user);
		return list;
	}

	/**
	 * 通过部门ID获取用户列表，仅返回用户id和name（树查询用户时用）
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<User> findUserByOfficeId(String officeId) {
		User user = new User();
		user.setOffice(new Office(officeId));
		List<User> list = userDao.findUserByOfficeId(user);
		return list;
	}

	@Transactional(readOnly = false)
	public void saveUser(User user) {

		if (StringUtils.isBlank(user.getId())) {
			user.preInsert();
			userDao.insert(user);
		} else {
			// 更新用户数据
			user.preUpdate();
			userDao.update(user);
		}
		if (StringUtils.isNotBlank(user.getId())) {
			// 更新用户与角色关联
			userDao.deleteUserRole(user);
			if (user.getRoleList() != null && user.getRoleList().size() > 0) {
				userDao.insertUserRole(user);
			} else {
				throw new GlobalException(user.getLoginName() + "没有设置角色");
			}
		}
	}

	/**
	 * 保存用户数据
	 * @param user
	 */
	@Transactional(readOnly = false)
	public void saveNewUser(User user) {
		if (StringUtils.isBlank(user.getId())) {
			user.preInsert();
			userDao.insert(user);
		} else {
			// 更新用户数据
			user.preUpdate();
			userDao.update(user);
		}
		if (StringUtils.isNotBlank(user.getId())) {
			if (user.getRoleList() != null && user.getRoleList().size() > 0) {
				// 更新用户与角色关联
				userDao.deleteUserRole(user);
				userDao.insertUserRole(user);
			}
		}
	}

	@Transactional(readOnly = false)
	public void saveRegUser(User user) {
		//user.preInsert();
		User sysUser = new User();
		sysUser.setId("1");
		user.setCreateBy(sysUser);
		user.setUpdateBy(sysUser);
		userDao.insert(user);
		if (StringUtils.isNotBlank(user.getId())) {
			// 更新用户与角色关联
			userDao.deleteUserRole(user);
			if (user.getRoleList() != null && user.getRoleList().size() > 0) {
				userDao.insertUserRole(user);
			} else {
				throw new GlobalException(user.getLoginName() + "没有设置角色");
			}
		}
	}

	@Transactional(readOnly = false)
	public void updateUserInfo(User user) {
		User oldUser = userDao.get(user.getId());
		//user.preUpdate();
		userDao.updateUserInfo(user);
	}

	@Transactional(readOnly = false)
	public void deleteUser(User user) {
		userDao.delete(user);

		HtCarFiles htCarFiles = new HtCarFiles();
		htCarFiles.setPhone(user.getLoginName());
		htCarFiles = htCarFilesDao.getCarFilesByPhone(htCarFiles);
		if(htCarFiles != null){
			htCarFilesDao.delete(htCarFiles);
		}
		HtDriverFile htDriverFile = htDriverFileDao.getDriverByUserId(user.getId());
		if(htDriverFile!= null){
			htDriverFileDao.delete(htDriverFile);
		}
		// // 清除权限缓存
		// systemRealm.clearAllCachedAuthorizationInfo();
	}

	@Transactional(readOnly = false)
	public int updatePasswordById(String id, String newPassword) {
		User user = new User(id);
		user.setPassword(entryptPassword(newPassword));
		int rows = userDao.updatePasswordById(user);
		return rows;
	}

	@Transactional(readOnly = false)
	public void updateUserLoginInfo(User user) {
		// 保存上次登录信息
		user.setOldLoginIp(user.getLoginIp());
		user.setOldLoginDate(user.getLoginDate());
		// 更新本次登录信息
		user.setLoginIp(IpUtils.getIpAddr());
		user.setLoginDate(new Date());
		userDao.updateLoginInfo(user);
	}

	/**
	 * 生成安全的密码，生成随机的16位salt并经过1024次 sha-1 hash
	 */
	public static String entryptPassword(String plainPassword) {
		String plain = Encodes.unescapeHtml(plainPassword);
		byte[] salt = Digests.generateSalt(SALT_SIZE);
		byte[] hashPassword = Digests.sha1(plain.getBytes(), salt, HASH_INTERATIONS);
		return Encodes.encodeHex(salt) + Encodes.encodeHex(hashPassword);
	}

	/**
	 * 验证密码
	 * @param plainPassword 明文密码
	 * @param password 密文密码
	 * @return 验证成功返回true
	 */
	public static boolean validatePassword(String plainPassword, String password) {
		String plain = Encodes.unescapeHtml(plainPassword);
		byte[] salt = Encodes.decodeHex(password.substring(0, 16));
		byte[] hashPassword = Digests.sha1(plain.getBytes(), salt, HASH_INTERATIONS);
		return password.equals(Encodes.encodeHex(salt) + Encodes.encodeHex(hashPassword));
	}

	// -- Role Service --//

	public Role getRole(String id) {
		return roleDao.get(id);
	}

	public Role getRoleByName(String name) {
		Role r = new Role();
		r.setName(name);
		return roleDao.getByName(r);
	}

	public Role getRoleByEnname(String enname) {
		Role r = new Role();
		r.setEnname(enname);
		return roleDao.getByEnname(r);
	}

	public List<Role> findRole(Role role) {
		return roleDao.findList(role);
	}

	@Transactional(readOnly = false)
	public void saveRole(Role role) {
		if (StringUtils.isBlank(role.getId())) {
			//role.preInsert();
			roleDao.insert(role);
		} else {
			//role.preUpdate();
			roleDao.update(role);
		}
		// 更新角色与菜单关联
		roleDao.deleteRoleMenu(role);
		if (role.getMenuList().size() > 0) {
			roleDao.insertRoleMenu(role);
		}
		// 更新角色与部门关联
		roleDao.deleteRoleOffice(role);
		if (role.getOfficeList().size() > 0) {
			roleDao.insertRoleOffice(role);
		}
	}

	@Transactional(readOnly = false)
	public void deleteRole(Role role) {
		roleDao.delete(role);
	}

	@Transactional(readOnly = false)
	public Boolean outUserInRole(Role role, User user) {
		List<Role> roles = user.getRoleList();
		for (Role e : roles) {
			if (e.getId().equals(role.getId())) {
				roles.remove(e);
				saveUser(user);
				return true;
			}
		}
		return false;
	}

	@Transactional(readOnly = false)
	public User assignUserToRole(Role role, User user) {
		if (user == null) {
			return null;
		}
		List<String> roleIds = user.getRoleIdList();
		if (roleIds.contains(role.getId())) {
			return null;
		}
		user.getRoleList().add(role);
		saveUser(user);
		return user;
	}

	// -- Menu Service --//

	public Menu getMenu(String id) {
		return menuDao.get(id);
	}

	@Transactional(readOnly = false)
	public void saveMenu(Menu menu) {

		// 获取父节点实体
		menu.setParent(this.getMenu(menu.getParent().getId()));

		// 获取修改前的parentIds，用于更新子节点的parentIds
		String oldParentIds = menu.getParentIds();

		// 设置新的父节点串
		menu.setParentIds(menu.getParent().getParentIds() + menu.getParent().getId() + ",");

		// 保存或更新实体
		if (StringUtils.isBlank(menu.getId())) {
			//menu.preInsert();
			menuDao.insert(menu);
		} else {
			//menu.preUpdate();
			menuDao.update(menu);
		}

		// 更新子节点 parentIds
		Menu m = new Menu();
		m.setParentIds("%," + menu.getId() + ",%");
		List<Menu> list = menuDao.findByParentIdsLike(m);
		for (Menu e : list) {
			e.setParentIds(e.getParentIds().replace(oldParentIds, menu.getParentIds()));
			menuDao.updateParentIds(e);
		}
	}

	@Transactional(readOnly = false)
	public void updateMenuSort(Menu menu) {
		menuDao.updateSort(menu);
	}

	@Transactional(readOnly = false)
	public void deleteMenu(Menu menu) {
		menuDao.delete(menu);
	}

	/**
	 * 获取Key加载信息
	 */
	public static boolean printKeyLoadMessage() {
		String productName = "陕西推诚新能源科技有限公司网络货运平台";
		String companyName = "msk";
		StringBuilder sb = new StringBuilder();
		sb.append("\r\n======================================================================\r\n");
		sb.append("\r\n    欢迎使用 " + productName + "  - Powered By " + companyName + "\r\n");
		sb.append("\r\n======================================================================\r\n");
		System.out.println(sb.toString());
		return true;
	}

	/**
	 * 根据部门分组查询数量
	 * @description getCountGroupByOffice
	 * @date 2018-7-3
	 * @author chuming
	 * @param user
	 * @return
	 */
	public List<User> getCountGroupByOffice(User user){
		//user.getSqlMap().put("dsf", BaseService.dataScopeFilter(user.getCurrentUser(), "o3", "u"));
		return userDao.getCountGroupByOffice(new User());
	}

	/**
	 * 手机端验证用户用户名是否存在
	 * @param loginName
	 * @return
	 */
	public int validataMobile(String loginName){
		return userDao.validataMobile(loginName);
	}

	/**
	 * 查询全部用户数目
	 * @return
	 */
	public long findAllCount(User user){
		return userDao.findAllCount(user);
	}

	/**
	 * 根据用户ID修改用户锁定信息
	 * @param param
	 */
	@Transactional(readOnly = false)
	public void updateLockInfoByUserId(Map<String, Object> param) {
		userDao.updateLockInfoByUserId(param);
	}

	/**
	 * 根据用户Id实时查询用户信息
	 * @param userId
	 * @return
	 */
	public User getDbUserById(String userId) {
		return userDao.get(userId);
	}

	/**
	 * 根据菜单获取用户列表
	 * @param param
	 * @return
	 */
	public List<User> selectUserByMenuId(Map<String, Object> param) {
		return userDao.selectUserByMenuId(param);
	}

	/**
	 * 根据用户名获取用户
	 * @param loginName
	 * @return
	 */
	public User getUserByLoginName(String loginName) {
		User user = userDao.getByLoginName(new User(null, loginName));
		return user;
	}
	
	@Override
	public void afterPropertiesSet() throws Exception {

	}

	/**
	 * 校验手机号是否存在
	 * @param mobile
	 * @return
	 */
	public boolean checkMobileExist(String mobile) {
		boolean existFlag = false;
		int rows = userDao.checkMobileUnique(mobile);
		if (rows > 0) {
			existFlag = true;
		}
		return existFlag;
	}
}
